package cn.edu.tju.ldj.analytics.alphas;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import cn.edu.tju.ldj.analytics.Const;
import cn.edu.tju.ldj.analytics.Factory;
import cn.edu.tju.ldj.analytics.utils.UtilFile;
import cn.edu.tju.ldj.analytics.vo.Contract;

public abstract class IAlphaEngine {
	protected static Logger logger;

	static {
		logger = Logger.getLogger(Alpha0.class.getName());
	}
	
	protected final int WINDOW_INDEX = 12;
	protected final int observeDateNum = 21;
	protected final Double gapThreshold = 0.036; // 控制回撤幅度的参数
	protected final Double gapNDayThreshold = 0.005; // 开仓的突破信号
	protected final Double slopeThreshold = 0.0006;

	protected boolean isLogger = false;
	protected boolean isDebug = false;
	protected List<Map<String, Object>> silverList = new ArrayList<Map<String, Object>>();
	protected Double silverNewPrice = 0.0;
	
	protected int fiveTenIndex = 365;
	protected int fiveTwnIndex = 365;
	protected int tenTwnIndex = 365;
	protected final int STAT_INIT = -1, STAT_RISE = 0, STAT_WAVE = 1,
			STAT_FALL = 2;
	protected final int POSITION_INIT = 0, POSITION_BUY_LIT = 1,
			POSITION_BUY_MID = 2, POSITION_BUY_HAV = 3, POSITION_SEL_LIT = -1,
			POSITION_SEL_MID = -2, POSITION_SEL_HAV = -3;
	protected int curState = STAT_INIT;
	protected int curPosition = POSITION_INIT;
	protected int shortTermStat = STAT_INIT;
	protected int midTermStat = STAT_INIT;
	protected int longTermStat = STAT_INIT;

	protected int tradeHands = 0; // 开仓手数
	protected Double capital = 10000.0;
	protected Double capitalShadow = 10000.0;

	protected List<String> orderList = new ArrayList<String>();

	protected DecimalFormat df = new DecimalFormat("#.00");

	protected Double returnsPercent = 0.0;
	protected Double sharpratioPercent = 0.0;
	protected Double drawdownPercent = 0.0;

	public void processSimulation(Contract ct, boolean isOutJson) {
		// TODO Auto-generated method stub
	}
	
	protected Double getSlope(String avgKey, int dayNum){
		Double slope = 0.0;
		if(dayNum > silverList.size()){
			return slope;
		}
		slope = ((Double) silverList.get(silverList.size() - 1).get(avgKey) - (Double) silverList
				.get(silverList.size() - 1 - dayNum).get(avgKey)) / (dayNum*(Double) silverList.get(silverList.size() - 1).get(avgKey));
//		System.out.println(slope);
		return slope;
	}
	
	protected boolean isSlopeRise(String avgKey){
		return getSlope(avgKey, WINDOW_INDEX/2) > (slopeThreshold)?true:false;
	}
	
	protected boolean isSlopeFall(String avgKey){
		return getSlope(avgKey, WINDOW_INDEX/2) < (slopeThreshold*(-1.0))?true:false;
	}
	
	protected boolean isSlopeShock(String avgKey){
		return Math.abs(getSlope(avgKey, WINDOW_INDEX/2)) < (slopeThreshold)?true:false;
	}

	protected boolean getNewPrices() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		logInfo("-+-+-+-+当前日期："
				+ sdf.format(new Date((Long) silverList.get(
						silverList.size() - 1).get("date"))));

		if (!isDebug) {
			// silverNewPrice = fetcher.getNewPrice(Constant.silverNewPriceUrl);
			if (silverNewPrice > 0.1) {
				return true;
			} else {
				logInfo("当前价格为0，休市中。。。");
			}
		}
		return false;
	}

	protected void getStrategy(Contract ct) {
		initBehaviors();
		orderList.clear();
		if (!getNewPrices()) {
			if (!isDebug) {
				return;
			}
		}
		getAvglineState();
		getWhereWeAre();
		informBoss();
	}

	protected void getAvglineState() {
		int flag = 0;
		int dice = 0;
		for (int i = silverList.size() - 1; i > (silverList.size()
				- observeDateNum - 1)
				&& i > 0; i--) {
			if ((Double) silverList.get(i).get("avg3")
					- (Double) silverList.get(i).get("avg2") > 0) {
				dice = 1;
			} else {
				dice = -1;
			}
			if (flag == 0) {
				flag = dice;
				tenTwnIndex = 1;
			} else if (flag == dice) {
				++tenTwnIndex;
			} else if (flag != dice) {
				--tenTwnIndex;
				// System.out.println(silverList.get(i+1).get("date") +
				// "  tenTwnIndex="+tenTwnIndex +
				// " lastItem="+(silverList.size()-1) + " i="+i);
				break;
			}
		}
		if (flag == 1) {
			longTermStat = STAT_FALL;
			// System.out.println("fall");
		} else if (flag == -1) {
			longTermStat = STAT_RISE;
			// System.out.println("rise");
		}

		flag = 0;
		dice = 0;
		for (int i = silverList.size() - 1; i > (silverList.size()
				- observeDateNum - 1)
				&& i > 0; i--) {
			if ((Double) silverList.get(i).get("avg3")
					- (Double) silverList.get(i).get("avg1") > 0) {
				dice = 1;
			} else {
				dice = -1;
			}
			if (flag == 0) {
				flag = dice;
				fiveTwnIndex = 1;
			} else if (flag == dice) {
				++fiveTwnIndex;
			} else if (flag != dice) {
				--fiveTwnIndex;
				// System.out.println(silverList.get(i+1).get("date") +
				// "  fiveTwnIndex="+fiveTwnIndex +
				// " lastItem="+(silverList.size()-1) + " i="+i);
				break;
			}
		}
		if (flag == 1) {
			midTermStat = STAT_FALL;
			// System.out.println("fall");
		} else if (flag == -1) {
			midTermStat = STAT_RISE;
			// System.out.println("rise");
		}

		flag = 0;
		dice = 0;
		for (int i = silverList.size() - 1; i > (silverList.size()
				- observeDateNum - 1)
				&& i > 0; i--) {
			if ((Double) silverList.get(i).get("avg2")
					- (Double) silverList.get(i).get("avg1") > 0) {
				dice = 1;
			} else {
				dice = -1;
			}
			if (flag == 0) {
				flag = dice;
				fiveTenIndex = 1;
			} else if (flag == dice) {
				++fiveTenIndex;
			} else if (flag != dice) {
				--fiveTenIndex;
				// System.out.println(silverList.get(i+1).get("date") +
				// "  fiveTenIndex="+fiveTenIndex +
				// " lastItem="+(silverList.size()-1) + " i="+i);
				break;
			}
		}
		if (flag == 1) {
			shortTermStat = STAT_FALL;
			// System.out.println("fall");
		} else if (flag == -1) {
			shortTermStat = STAT_RISE;
			// System.out.println("rise");
		}
	}

	protected void getWhereWeAre() {
	}

	protected boolean isLotus() {
		double fivAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg1");
		double tenAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg2");
		double twnAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg3");
		double low = (Double) silverList.get(silverList.size() - 1).get("low");
		double open = (Double) silverList.get(silverList.size() - 1)
				.get("open");
		double close = (Double) silverList.get(silverList.size() - 1).get(
				"close");
		if ((close > fivAvg && close > tenAvg && close > twnAvg)
				&& (low < (tenAvg + twnAvg) / 2)) {// twnAvg
			return true;
		} else if ((close - open)
				/ (Double) silverList.get(silverList.size() - 1).get("avg1") > gapThreshold) {
			return true;
		} else {
			return false;
		}
	}

	protected boolean isGuillotine() {
		double fivAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg1");
		double tenAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg2");
		double twnAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg3");
		double high = (Double) silverList.get(silverList.size() - 1)
				.get("high");
		double open = (Double) silverList.get(silverList.size() - 1)
				.get("open");
		double close = (Double) silverList.get(silverList.size() - 1).get(
				"close");
		if ((close < fivAvg && close < tenAvg && close < (twnAvg * 0.7 + tenAvg) / 1.7)
				&& (high > (tenAvg + fivAvg) / 2)) {//
			return true;
		} else if ((open - close)
				/ (Double) silverList.get(silverList.size() - 1).get("avg1") > gapThreshold) {
			return true;
		} else {
			return false;
		}
	}

	protected boolean isProceedGap() {
		double fivAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg1");
		double tenAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg2");
		double twnAvg = (Double) silverList.get(silverList.size() - 1).get(
				"avg3");
		double gap = Math.abs(twnAvg - tenAvg) + Math.abs(twnAvg - fivAvg)
				+ Math.abs(fivAvg - tenAvg);
		return gap
				/ ((Double) silverList.get(silverList.size() - 1).get("avg3") * 3) > gapNDayThreshold ? true
				: false;
	}

	protected boolean isProceedGap(int dayNum) {
		double gap = 0.0;
		for (int i = 0; i < dayNum; i++) {
			double fivAvg = (Double) silverList.get(silverList.size() - 1 - i)
					.get("avg1");
			double tenAvg = (Double) silverList.get(silverList.size() - 1 - i)
					.get("avg2");
			double twnAvg = (Double) silverList.get(silverList.size() - 1 - i)
					.get("avg3");
			gap += Math.abs(twnAvg - tenAvg) + Math.abs(twnAvg - fivAvg)
					+ Math.abs(fivAvg - tenAvg);
		}
		gap = gap / dayNum;
		return gap
				/ ((Double) silverList.get(silverList.size() - 1).get("avg3") * 3) > gapNDayThreshold ? true
				: false;
	}

	protected void initBehaviors() {
		switch (tradeHands) {
		case 0:
			curPosition = POSITION_INIT;
			break;
		case 1:
			curPosition = POSITION_BUY_LIT;
			break;
		case 2:
			curPosition = POSITION_BUY_MID;
			break;
		case 3:
			curPosition = POSITION_BUY_HAV;
			break;
		case -1:
			curPosition = POSITION_SEL_LIT;
			break;
		case -2:
			curPosition = POSITION_SEL_MID;
			break;
		case -3:
			curPosition = POSITION_SEL_HAV;
			break;
		}
	}

	protected void getWhatToDo(int position) {
		if (position == curPosition) {
			return;
		}
		switch (position) {
		case POSITION_INIT:
			switch (curPosition) {
			case POSITION_INIT:
				break;
			case POSITION_BUY_HAV:
				selFree(POSITION_BUY_HAV);
				break;
			case POSITION_BUY_LIT:
				selFree(POSITION_BUY_LIT);
				break;
			case POSITION_BUY_MID:
				selFree(POSITION_BUY_MID);
				break;
			case POSITION_SEL_HAV:
				buyFree(POSITION_SEL_HAV);
				break;
			case POSITION_SEL_LIT:
				buyFree(POSITION_SEL_LIT);
				break;
			case POSITION_SEL_MID:
				buyFree(POSITION_SEL_MID);
				break;
			default:
				break;
			}
			break;
		case POSITION_BUY_HAV:
			switch (curPosition) {
			case POSITION_INIT:
				buyOpen(POSITION_BUY_HAV);
				break;
			case POSITION_BUY_HAV:
				break;
			case POSITION_BUY_LIT:
				buyOpen(POSITION_BUY_MID);
				break;
			case POSITION_BUY_MID:
				buyOpen(POSITION_BUY_LIT);
				break;
			case POSITION_SEL_HAV:
				buyFree(POSITION_SEL_HAV);
				buyOpen(POSITION_BUY_HAV);
				break;
			case POSITION_SEL_LIT:
				buyFree(POSITION_SEL_LIT);
				buyOpen(POSITION_BUY_HAV);
				break;
			case POSITION_SEL_MID:
				buyFree(POSITION_SEL_MID);
				buyOpen(POSITION_BUY_HAV);
				break;
			default:
				break;
			}
			break;
		case POSITION_BUY_LIT:
			switch (curPosition) {
			case POSITION_INIT:
				buyOpen(POSITION_BUY_LIT);
				break;
			case POSITION_BUY_HAV:
				selFree(POSITION_BUY_MID);
				break;
			case POSITION_BUY_LIT:
				break;
			case POSITION_BUY_MID:
				selFree(POSITION_BUY_LIT);
				break;
			case POSITION_SEL_HAV:
				buyFree(POSITION_SEL_HAV);
				buyOpen(POSITION_BUY_LIT);
				break;
			case POSITION_SEL_LIT:
				buyFree(POSITION_SEL_LIT);
				buyOpen(POSITION_BUY_LIT);
				break;
			case POSITION_SEL_MID:
				buyFree(POSITION_SEL_MID);
				buyOpen(POSITION_BUY_LIT);
				break;
			default:
				break;
			}
			break;
		case POSITION_BUY_MID:
			switch (curPosition) {
			case POSITION_INIT:
				buyOpen(POSITION_BUY_MID);
				break;
			case POSITION_BUY_HAV:
				selFree(POSITION_BUY_LIT);
				break;
			case POSITION_BUY_LIT:
				buyOpen(POSITION_BUY_LIT);
				break;
			case POSITION_BUY_MID:
				break;
			case POSITION_SEL_HAV:
				buyFree(POSITION_SEL_HAV);
				buyOpen(POSITION_BUY_MID);
				break;
			case POSITION_SEL_LIT:
				buyFree(POSITION_SEL_LIT);
				buyOpen(POSITION_BUY_MID);
				break;
			case POSITION_SEL_MID:
				buyFree(POSITION_SEL_MID);
				buyOpen(POSITION_BUY_MID);
				break;
			default:
				break;
			}
			break;
		case POSITION_SEL_HAV:
			switch (curPosition) {
			case POSITION_INIT:
				selOpen(POSITION_SEL_HAV);
				break;
			case POSITION_BUY_HAV:
				selFree(POSITION_BUY_HAV);
				selOpen(POSITION_SEL_HAV);
				break;
			case POSITION_BUY_LIT:
				selFree(POSITION_BUY_LIT);
				selOpen(POSITION_SEL_HAV);
				break;
			case POSITION_BUY_MID:
				selFree(POSITION_BUY_MID);
				selOpen(POSITION_SEL_HAV);
				break;
			case POSITION_SEL_HAV:
				break;
			case POSITION_SEL_LIT:
				selOpen(POSITION_SEL_MID);
				break;
			case POSITION_SEL_MID:
				selOpen(POSITION_SEL_LIT);
				break;
			default:
				break;
			}
			break;
		case POSITION_SEL_LIT:
			switch (curPosition) {
			case POSITION_INIT:
				selOpen(POSITION_SEL_LIT);
				break;
			case POSITION_BUY_HAV:
				selFree(POSITION_BUY_HAV);
				selOpen(POSITION_SEL_LIT);
				break;
			case POSITION_BUY_LIT:
				selFree(POSITION_BUY_LIT);
				selOpen(POSITION_SEL_LIT);
				break;
			case POSITION_BUY_MID:
				selFree(POSITION_BUY_MID);
				selOpen(POSITION_SEL_LIT);
				break;
			case POSITION_SEL_HAV:
				buyFree(POSITION_BUY_MID);
				break;
			case POSITION_SEL_LIT:
				break;
			case POSITION_SEL_MID:
				buyFree(POSITION_BUY_LIT);
				break;
			default:
				break;
			}
			break;
		case POSITION_SEL_MID:
			switch (curPosition) {
			case POSITION_INIT:
				selOpen(POSITION_SEL_MID);
				break;
			case POSITION_BUY_HAV:
				selFree(POSITION_BUY_HAV);
				selOpen(POSITION_SEL_MID);
				break;
			case POSITION_BUY_LIT:
				selFree(POSITION_BUY_LIT);
				selOpen(POSITION_SEL_MID);
				break;
			case POSITION_BUY_MID:
				selFree(POSITION_BUY_MID);
				selOpen(POSITION_SEL_MID);
				break;
			case POSITION_SEL_HAV:
				buyFree(POSITION_BUY_LIT);
				break;
			case POSITION_SEL_LIT:
				selOpen(POSITION_SEL_LIT);
				break;
			case POSITION_SEL_MID:
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		curPosition = position;
	}

	protected boolean isTriRise() {// 连续三日纯涨
		if (silverList.size() < 3) {
			return false;
		}

		for (int i = 0; i < 3; i++) {
			if ((Double) silverList.get(silverList.size() - 1 - i).get("open")
					- (Double) silverList.get(silverList.size() - 1 - i).get(
							"close") > 0) {
				return false;
			}
		}
		return true;
	}

	protected boolean isTwiFall() {
		if (silverList.size() < 3) {
			return false;
		}

		for (int i = 0; i < 2; i++) {
			if ((Double) silverList.get(silverList.size() - 1 - i).get("open")
					- (Double) silverList.get(silverList.size() - 1 - i).get(
							"close") <= 0) {
				return false;
			}
		}
		return true;
	}
	
	protected boolean isSuccessiveOverAvg(String avgKey, int dayNum){//判断前几日价格是否在跨越或突破均线
		if (silverList.size() < dayNum) {
			return false;
		}
		else{
			for (int i = 0; i < dayNum; i++) {
				if (((Double) silverList.get(silverList.size() - 1 - i).get("close")
						- (Double) silverList.get(silverList.size() - 1 - i).get(avgKey) < 0) && ((Double) silverList.get(silverList.size() - 1 - i).get("open")
						- (Double) silverList.get(silverList.size() - 1 - i).get(avgKey) < 0)){
					return false;
				}
			}
		}
		return true;
	}
	
	protected boolean isSuccessiveBelowAvg(String avgKey, int dayNum){
		if (silverList.size() < dayNum) {
			return false;
		}
		else{
			for (int i = 0; i < dayNum; i++) {
				if (((Double) silverList.get(silverList.size() - 1 - i).get("close")
						- (Double) silverList.get(silverList.size() - 1 - i).get(avgKey) > 0) && ((Double) silverList.get(silverList.size() - 1 - i).get("open")
						- (Double) silverList.get(silverList.size() - 1 - i).get(avgKey) > 0)){
					return false;
				}
			}
		}
		return true;
	}
	
	protected boolean isLineOver(String srcKey, String tagKey){
		if((Double) silverList.get(silverList.size() - 1).get(srcKey) - (Double) silverList.get(silverList.size() - 1).get(tagKey) > 0){
			return true;
		}
		return false;
	}

	protected boolean isTwiTriUpAvgTwn() {// 前三日有最起码两日突破廿日线，且最近一日穿插廿日线
		if (silverList.size() < 3) {
			return false;
		}
		if ((Double) silverList.get(silverList.size() - 1).get("high")
				- (Double) silverList.get(silverList.size() - 1).get("avg3") > 0) {
			if ((Double) silverList.get(silverList.size() - 2).get("high")
					- (Double) silverList.get(silverList.size() - 2)
							.get("avg3") > 0) {
				return true;
			}
			if ((Double) silverList.get(silverList.size() - 3).get("high")
					- (Double) silverList.get(silverList.size() - 3)
							.get("avg3") > 0) {
				return true;
			}
		}
		return false;
	}

	protected boolean isObveTwnAvg() {// 前两日均收于廿日线上方
		if (silverList.size() < 3) {
			return false;
		}
		if ((Double) silverList.get(silverList.size() - 1).get("close")
				- (Double) silverList.get(silverList.size() - 1).get("avg3") > 0
				&& (Double) silverList.get(silverList.size() - 2).get("close")
						- (Double) silverList.get(silverList.size() - 2).get(
								"avg3") > 0) {
			return true;
		}
		return false;
	}

	protected void buyOpen(int units) {
		tradeHands += Math.abs(units);
		capital -= Math.abs(units) * silverNewPrice;
		logInfo("capital---" + capital);
		String newOrder = "买入开仓：" + Math.abs(units) + "手，价格："
				+ formatDouble(silverNewPrice) + "，目前持仓" + tradeHands + "手。";
		orderList.add(newOrder);
	}

	protected void buyFree(int units) {
		tradeHands += Math.abs(units);
		capital -= Math.abs(units) * silverNewPrice;
		logInfo("capital---" + capital);
		String newOrder = "买入平仓：" + Math.abs(units) + "手，价格："
				+ formatDouble(silverNewPrice) + "，目前持仓" + tradeHands + "手。";
		if (tradeHands == 0) {
			newOrder += "浮动盈亏：" + formatDouble(capital - capitalShadow);
		}
		orderList.add(newOrder);
	}

	protected void selOpen(int units) {
		tradeHands -= Math.abs(units);
		capital += Math.abs(units) * silverNewPrice;
		logInfo("capital---" + capital);
		String newOrder = "卖出开仓：" + Math.abs(units) + "手，价格："
				+ formatDouble(silverNewPrice) + "，目前持仓" + tradeHands + "手。";
		orderList.add(newOrder);
	}

	protected void selFree(int units) {
		tradeHands -= Math.abs(units);
		capital += Math.abs(units) * silverNewPrice;
		logInfo("capital---" + capital);
		String newOrder = "卖出平仓：" + Math.abs(units) + "手，价格："
				+ formatDouble(silverNewPrice) + "，目前持仓" + tradeHands + "手。";
		if (tradeHands == 0) {
			newOrder += "浮动盈亏：" + formatDouble(capital - capitalShadow);
		}
		orderList.add(newOrder);
	}

	protected double formatDouble(Double value) {
		return Math.round(value * 10000) / 10000.0000;
	}

	protected void informBoss() {
		// Mailer mailer = new Mailer();
		// String subject = "策略：";
		for (String content : orderList) {
			logInfo(content);
			// for (String address : Constant.emailListBoss) {
			try {
				// if (!isDebug) {
				// // mailer.sendMail(address, subject, content);
				// }
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			// }
		}
	}

	protected void logInfo(String content) {
		if (isLogger) {
			logger.info(content);
		}
	}

	protected void logDebug(String content) {
		if (isLogger) {
			logger.debug(content);
		}
	}

	protected List<Map<String, Object>> initEnviroment(Contract ct, boolean isOutJson) {
		isDebug = true;
//		isLogger = isOutJson;
		isLogger = false;
		silverList = ct.getCtrctDayDataLst();

		List<Map<String, Object>> silverListShadow = new ArrayList<Map<String, Object>>();
		
		
		for (int i = 0; i < silverList.size(); i++) {
			silverListShadow.add(silverList.get(i));
		}
		
		Map<String, Object> fakeItem = new HashMap<String, Object>();
		fakeItem.put(
				"date",
				(Long) silverListShadow.get(silverListShadow.size() - 1).get(
						"date") + 86400000);
		fakeItem.put("open", silverListShadow.get(silverListShadow.size() - 1)
				.get("open"));
		fakeItem.put("high", silverListShadow.get(silverListShadow.size() - 1)
				.get("high"));
		fakeItem.put("low", silverListShadow.get(silverListShadow.size() - 1)
				.get("low"));
		fakeItem.put("close", silverListShadow.get(silverListShadow.size() - 1)
				.get("close"));
		fakeItem.put("volume", silverListShadow
				.get(silverListShadow.size() - 1).get("volume"));
		fakeItem.put("avg1", silverListShadow.get(silverListShadow.size() - 1)
				.get("avg1"));
		fakeItem.put("avg2", silverListShadow.get(silverListShadow.size() - 1)
				.get("avg2"));
		fakeItem.put("avg3", silverListShadow.get(silverListShadow.size() - 1)
				.get("avg3"));
		fakeItem.put("avg4", silverListShadow.get(silverListShadow.size() - 1)
				.get("avg4"));
		silverListShadow.add(fakeItem);
		
		return silverListShadow;
	}

	protected void strategyTest(Contract ct, boolean isOutJson) {
		List<Map<String, Object>> silverListShadow = initEnviroment(ct, isOutJson);

		String priceData = "{\"data\":\n\t[";
		String profitData = "{\"data\":\n\t[";
		String positionData = "{\"data\":\n\t[";

		double basePrice = silverListShadow.size() > 0 ? (Double) silverListShadow
				.get(silverListShadow.size() - 1).get("avg4") * 3 : 0.00;
		double profitTem = basePrice;
		Double capitcalTem = 0.0;
		for (int i = observeDateNum - 1; i < silverListShadow.size(); i++) {
			if (i == silverListShadow.size() - 1) {
				silverNewPrice = (Double) silverListShadow.get(i).get("close");
			} else {
				silverNewPrice = ((Double) silverListShadow.get(i + 1).get(
						"open") * 0.8 + (Double) silverListShadow.get(i + 1)
						.get("close") * 0.2);
				if (i == (observeDateNum - 1)) {
					profitTem = basePrice;
				} else {
					profitTem = capital + silverNewPrice * tradeHands
							- 10000.00 + basePrice;
				}
				if (isOutJson || ct.getCtrctName().contains("Index")) {
					priceData += "\n\t\t["
							+ (Long) silverListShadow.get(i + 1).get("date")
							+ "," + silverNewPrice + "],";
					profitData += "\n\t\t["
							+ (Long) silverListShadow.get(i + 1).get("date")
							+ "," + (profitTem) + "],";
					if (i == observeDateNum) {
						positionData += ("\n\t\t["
								+ (Long) silverListShadow.get(i + 1)
										.get("date") + "," + 25 + "],");
					} else {
						positionData += ("\n\t\t["
								+ (Long) silverListShadow.get(i + 1)
										.get("date") + "," + (25 + tradeHands) + "],");
					}
				}
			}
			if (i == (observeDateNum - 1)) {
				continue;
			}
			silverList = silverListShadow.subList(0, i);

			getStrategy(ct);
			if (i > observeDateNum) {
				if ((profitTem - capitcalTem) / capitcalTem < drawdownPercent) {
					drawdownPercent = (profitTem - capitcalTem) / capitcalTem;
				}
			}
			capitcalTem = profitTem;
		}

		sharpratioPercent = (profitTem - basePrice)
				/ (basePrice * silverListShadow.size());
		returnsPercent = (profitTem - basePrice) / basePrice;
		// System.out.println(returnsPercent);
		ct.setCtrctProfitPct(Double.valueOf(df.format(returnsPercent * 100.00)));
		// System.out.println(ct.getCtrctProfitPct());
		ct.setCtrctSharpRatio(Double.valueOf(df
				.format(sharpratioPercent * 100.00)));
		ct.setCtrctDrawDownPct(Double.valueOf(df
				.format(drawdownPercent * 100.00)));

		if (isOutJson) {
			priceData = priceData.substring(0, priceData.length() - 1);
			priceData += "\n]}";
			// System.out.println(priceData);
			UtilFile.writeFile(
					Factory.utilParam.getWebappsPath()
							+ Factory.utilParam
									.getParam(Const.PARAM_FILE_SECTION_TARGET_PATH)
							+ "price.json", priceData);

			profitData = profitData.substring(0, profitData.length() - 1);
			profitData += "\n]}";
			// System.out.println(profitData);
			UtilFile.writeFile(
					Factory.utilParam.getWebappsPath()
							+ Factory.utilParam
									.getParam(Const.PARAM_FILE_SECTION_TARGET_PATH)
							+ "currency.json", profitData);

			positionData = positionData.substring(0, positionData.length() - 1);
			positionData += "\n]}";
			// System.out.println(positionData);
			UtilFile.writeFile(
					Factory.utilParam.getWebappsPath()
							+ Factory.utilParam
									.getParam(Const.PARAM_FILE_SECTION_TARGET_PATH)
							+ "position.json", positionData);
		}
	}
}
